#include "ModRunObserver.h"
#include <QDebug>

#include "../Output/FactoryOutput.h"

#include "Gof23/Gof_Observer/ObserverBar.h"
#include "Gof23/Gof_Observer/ObserverUI.h"
#include "Gof23/Gof_Observer/SubjectA.h"

//观察者模式的ModRun（Observer）;
ModRunObserver::ModRunObserver()
{
    //模式名称;
    m_strModelName = "观察者模式（Observer）;";
    //模式描述;
    m_strModelDesc = "观察者模式：定义对象间的一种一对多的依赖关系，当一个对象的状态发生改变时，所有依赖于它的对象都要得到通知并自动更新。\r\n"
                     "观察者模式从根本上讲必须包含两个角色：观察者和被观察对象。\r\n"
                     "被观察对象自身应该包含一个容器来存放观察者对象，当被观察者自身发生改变时通知容器内所有的观察者对象自动更新。\r\n"
                     "观察者对象可以注册到被观察者的中，完成注册后可以检测被观察者的变化，接收被观察者的通知。当然观察者也可以被注销掉，停止对被观察者的监控。\r\n"
                     ;
}

//初始化显示模式;
void ModRunObserver::InitDisplay()
{
    qDebug() << m_strModelName;
    std::shared_ptr<IOutput> pOutPut = FactoryOutput::GetInstance()->CreateDescOutput();
    if (pOutPut)
    {
        std::initializer_list<QString> outList{ m_strModelName,m_strModelDesc};
        pOutPut->OutPut(outList);
    }
}

//返回模式类型;
EnumModRun ModRunObserver::GetEnum()
{
    return emModRunObserver;
}

//运行模式;
void ModRunObserver::ModRun()
{
    std::shared_ptr<IOutput> pOutPut = FactoryOutput::GetInstance()->CreateRunOutput();
    if (pOutPut)
    {
        std::initializer_list<QString> outListStart{ "========观察者模式 start:=======" };
        std::initializer_list<QString> outListEnd{ "========观察者模式 end:=======" };
        pOutPut->OutPut(outListStart);

        //观察者模式;
        SubjectA subA;
        std::shared_ptr<IObserver> obBar(new ObserverBar);
        std::shared_ptr<IObserver> obUI(new ObserverUI);
        subA.RegiserObserver(obBar);
        subA.RegiserObserver(obUI);

        subA.SetStatus("开始状态");

        subA.RemoveObserver(obUI);

        subA.SetStatus("中间状态");

        subA.RemoveObserver(obBar);
        subA.RegiserObserver(obUI);

        subA.SetStatus("结束状态");

        subA.RemoveObserver(obBar);
        subA.RemoveObserver(obUI);

        pOutPut->OutPut(outListEnd);
    }

}

InterFaceModRun* ModRunObserver::CreateMe()
{
    return new ModRunObserver();
}
